{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "592892bb-2fc6-43e4-9ac4-14a36c4cac20",
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "be3c54d3-5ac4-4ad1-8619-929dcb1006ec",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_excel(r'C:\\df_merge.xlsx')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0796c078-4660-4991-96ac-acfab9f40a90",
   "metadata": {},
   "source": [
    "# 1. Figure 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "69cb663d-7bdf-4191-86b0-d99a052c74c6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a 3x2 subplot with larger figure size for better readability\n",
    "fig, axes = plt.subplots(3, 2, figsize=(18, 14))\n",
    "axes = axes.flatten()\n",
    "\n",
    "categorical_vars = ['Age', 'Gender', 'Income', 'Education', 'Political Orientation', 'Religion']\n",
    "patterns = ['/', '\\\\', '|', '-', '+', 'x', 'o', 'O', '.', '*']\n",
    "\n",
    "# Define a color palette\n",
    "colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b']\n",
    "\n",
    "\n",
    "# Title labels with alphabetical indexing\n",
    "title_labels = ['(a)', '(b)', '(c)', '(d)', '(e)', '(f)']\n",
    "\n",
    "# Generate grouped bar charts with different patterns and colors\n",
    "for i, var in enumerate(categorical_vars):\n",
    "    category_counts = df.groupby(['Position', var]).size().unstack().fillna(0)\n",
    "    category_counts.plot(kind='bar', ax=axes[i], width=0.7, color=colors[:len(category_counts.columns)])\n",
    "    \n",
    "    # Apply consistent patterns to bars within each subplot\n",
    "    bars = axes[i].containers\n",
    "    for j, bar_group in enumerate(bars):\n",
    "        for bar in bar_group:\n",
    "            bar.set_hatch(patterns[j % len(patterns)])\n",
    "            # Add text labels on the bars\n",
    "            height = bar.get_height()\n",
    "            if height > 0:\n",
    "                axes[i].text(bar.get_x() + bar.get_width()/2, height, int(height), \n",
    "                             ha='center', va='bottom', fontsize=18)\n",
    "\n",
    "    # Add title with (a), (b), etc. and extra padding\n",
    "    axes[i].set_title(f\"{title_labels[i]} Distribution of {var} by Position\", fontsize=26, pad=16)\n",
    "\n",
    "    # Remove x-axis label name but keep ticks\n",
    "    axes[i].set_xlabel(\"\")\n",
    "    \n",
    "    # Increase y-axis label font size\n",
    "    axes[i].set_ylabel(\"\", fontsize=12)\n",
    "    \n",
    "    # Increase x and y tick font size\n",
    "    axes[i].tick_params(axis='x', rotation=0, labelsize=16)\n",
    "    axes[i].tick_params(axis='y', labelsize=17)\n",
    "    axes[i].grid(True)\n",
    "    \n",
    "    # Increase legend size\n",
    "    axes[i].legend(title=var, bbox_to_anchor=(1.05, 1), loc='upper left', fontsize=17, title_fontsize=17)\n",
    "\n",
    "# Adjust layout for clarity\n",
    "plt.tight_layout()\n",
    "\n",
    "# Save figure as PNG\n",
    "fig_path = r\"C:\\figure_1.png\"\n",
    "plt.savefig(fig_path, dpi=300, bbox_inches='tight')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ac8b5d30-285b-43fa-8e0c-5ccdd194fc71",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "313f97e1-0ca0-4e1e-92f8-1ac2988cb2c5",
   "metadata": {},
   "source": [
    "# 2. Figure 2(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c46d7dba-1507-4160-b86e-514aadf1f242",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Split the data into two groups\n",
    "group1 = df[df['Position'].isin(['Pro-Impeachment'])]\n",
    "group2 = df[df['Position'].isin(['Anti-Impeachment'])]\n",
    "\n",
    "# Calculate mean and std for each group\n",
    "mean1 = group1['Impeachment Support'].mean()\n",
    "std1 = group1['Impeachment Support'].std()\n",
    "mean2 = group2['Impeachment Support'].mean()\n",
    "std2 = group2['Impeachment Support'].std()\n",
    "\n",
    "# **Set bins to align bars with 1, 2, 3, 4, 5**\n",
    "bins = np.array([0.5, 1.5, 2.5, 3.5, 4.5, 5.5])  # Ensures bars are centered on 1, 2, 3, 4, 5\n",
    "\n",
    "# Compute histogram data without plotting\n",
    "n1, _ = np.histogram(group1['Impeachment Support'], bins=bins)\n",
    "n2, _ = np.histogram(group2['Impeachment Support'], bins=bins)\n",
    "\n",
    "# Define bar width and shift each group slightly\n",
    "bar_width = 0.3  # Ensure bars are not too wide\n",
    "shift = bar_width / 2  # Shift amount\n",
    "\n",
    "# Plot the histograms\n",
    "fig, ax = plt.subplots(figsize=(5, 7))\n",
    "\n",
    "# X positions for bars (centers on 1, 2, 3, 4, 5)\n",
    "bar_positions = np.array([1, 2, 3, 4, 5])\n",
    "\n",
    "# Plot for group 1 (Pro-Impeachment)\n",
    "ax.bar(bar_positions - shift, n1, width=bar_width, color='#b30000', \n",
    "       alpha=1, label='Pro-Impeachment', edgecolor='black', hatch='//')\n",
    "\n",
    "# Add numbers on bars for group 1 (except zero)\n",
    "for count, x_pos in zip(n1, bar_positions):\n",
    "    if count > 0:\n",
    "        ax.text(x_pos - shift, count + 10, str(int(count)), \n",
    "                ha='center', fontsize=12, color='#b30000')\n",
    "\n",
    "ax.axvline(mean1, color='#b30000', linestyle='dashed', linewidth=3)\n",
    "textstr1 = f'Mean: {mean1:.4f}\\nStd Dev: {std1:.4f}'\n",
    "props = dict(boxstyle='round', facecolor='white', alpha=0.5)\n",
    "ax.text(0.03, 0.85, textstr1, transform=ax.transAxes, fontsize=14, \n",
    "        verticalalignment='top', bbox=props, color='#b30000')\n",
    "\n",
    "# Plot for group 2 (Anti-Impeachment)\n",
    "ax.bar(bar_positions + shift, n2, width=bar_width, color='#008ae6', \n",
    "       alpha=1, label='Anti-Impeachment', edgecolor='black', hatch='xx')\n",
    "\n",
    "# Add numbers on bars for group 2 (except zero)\n",
    "for count, x_pos in zip(n2, bar_positions):\n",
    "    if count > 0:\n",
    "        ax.text(x_pos + shift, count + 10, str(int(count)), \n",
    "                ha='center', fontsize=12, color='#008ae6')\n",
    "\n",
    "ax.axvline(mean2, color='#008ae6', linestyle='dashed', linewidth=3)\n",
    "textstr2 = f'Mean: {mean2:.4f}\\nStd Dev: {std2:.4f}'\n",
    "props = dict(boxstyle='round', facecolor='white', alpha=0.5)\n",
    "ax.text(0.03, 0.75, textstr2, transform=ax.transAxes, fontsize=14, \n",
    "        verticalalignment='top', bbox=props, color='#008ae6')\n",
    "\n",
    "# Set labels and tick parameters\n",
    "ax.set_xlabel('Impeachment Support', fontsize=14)\n",
    "ax.set_ylabel('', fontsize=18)\n",
    "ax.tick_params(axis='x', labelsize=14)\n",
    "ax.tick_params(axis='y', labelsize=12)\n",
    "\n",
    "# **Set x-axis to show only 1, 2, 3, 4, 5**\n",
    "ax.set_xticks([1, 2, 3, 4, 5])  # Ensure only these values appear on x-axis\n",
    "\n",
    "ax.grid(True)\n",
    "ax.legend(loc='upper left', fontsize=14)\n",
    "\n",
    "# Set y-axis range\n",
    "ax.set_ylim(0, 1000)  # <---- Set y-axis from 0 to 1000\n",
    "\n",
    "# Adjust layout\n",
    "plt.tight_layout()\n",
    "\n",
    "# Save the figure\n",
    "evi_histogram_path = 'fig_2a.png'\n",
    "plt.savefig(evi_histogram_path)\n",
    "\n",
    "# Display the figure\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d63b3f01-7cf8-47de-859d-56d2aa01714d",
   "metadata": {},
   "source": [
    "# 2. Figure 2(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3dc62f8b-5e73-4047-8f71-ce31f794b0ee",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Split the data into two groups\n",
    "group1 = df[df['Position'].isin(['Pro-Impeachment'])]\n",
    "group2 = df[df['Position'].isin(['Anti-Impeachment'])]\n",
    "\n",
    "# Calculate mean and std for each group\n",
    "mean1 = group1['Martial Law Limits Democracy'].mean()\n",
    "std1 = group1['Martial Law Limits Democracy'].std()\n",
    "mean2 = group2['Martial Law Limits Democracy'].mean()\n",
    "std2 = group2['Martial Law Limits Democracy'].std()\n",
    "\n",
    "# **Set bins to align bars with 1, 2, 3, 4, 5**\n",
    "bins = np.array([0.5, 1.5, 2.5, 3.5, 4.5, 5.5])  # Ensures bars are centered on 1, 2, 3, 4, 5\n",
    "\n",
    "# Compute histogram data without plotting\n",
    "n1, _ = np.histogram(group1['Martial Law Limits Democracy'], bins=bins)\n",
    "n2, _ = np.histogram(group2['Martial Law Limits Democracy'], bins=bins)\n",
    "\n",
    "# Define bar width and shift each group slightly\n",
    "bar_width = 0.3  # Ensure bars are not too wide\n",
    "shift = bar_width / 2  # Shift amount\n",
    "\n",
    "# Plot the histograms\n",
    "fig, ax = plt.subplots(figsize=(5, 7))\n",
    "\n",
    "# X positions for bars (centers on 1, 2, 3, 4, 5)\n",
    "bar_positions = np.array([1, 2, 3, 4, 5])\n",
    "\n",
    "# Plot for group 1 (Pro-Impeachment)\n",
    "ax.bar(bar_positions - shift, n1, width=bar_width, color='#b30000', \n",
    "       alpha=1, label='Pro-Impeachment', edgecolor='black', hatch='//')\n",
    "\n",
    "# Add numbers on bars for group 1 (except zero)\n",
    "for count, x_pos in zip(n1, bar_positions):\n",
    "    if count > 0:\n",
    "        ax.text(x_pos - shift, count + 10, str(int(count)), \n",
    "                ha='center', fontsize=12, color='#b30000')\n",
    "\n",
    "ax.axvline(mean1, color='#b30000', linestyle='dashed', linewidth=3)\n",
    "textstr1 = f'Mean: {mean1:.4f}\\nStd Dev: {std1:.4f}'\n",
    "props = dict(boxstyle='round', facecolor='white', alpha=0.5)\n",
    "ax.text(0.03, 0.85, textstr1, transform=ax.transAxes, fontsize=14, \n",
    "        verticalalignment='top', bbox=props, color='#b30000')\n",
    "\n",
    "# Plot for group 2 (Anti-Impeachment)\n",
    "ax.bar(bar_positions + shift, n2, width=bar_width, color='#008ae6', \n",
    "       alpha=1, label='Anti-Impeachment', edgecolor='black', hatch='xx')\n",
    "\n",
    "# Add numbers on bars for group 2 (except zero)\n",
    "for count, x_pos in zip(n2, bar_positions):\n",
    "    if count > 0:\n",
    "        ax.text(x_pos + shift, count + 10, str(int(count)), \n",
    "                ha='center', fontsize=12, color='#008ae6')\n",
    "\n",
    "ax.axvline(mean2, color='#008ae6', linestyle='dashed', linewidth=3)\n",
    "textstr2 = f'Mean: {mean2:.4f}\\nStd Dev: {std2:.4f}'\n",
    "props = dict(boxstyle='round', facecolor='white', alpha=0.5)\n",
    "ax.text(0.03, 0.75, textstr2, transform=ax.transAxes, fontsize=14, \n",
    "        verticalalignment='top', bbox=props, color='#008ae6')\n",
    "\n",
    "# Set labels and tick parameters\n",
    "ax.set_xlabel('Martial Law Limits Democracy', fontsize=14)\n",
    "ax.set_ylabel('', fontsize=18)\n",
    "ax.tick_params(axis='x', labelsize=14)\n",
    "ax.tick_params(axis='y', labelsize=12)\n",
    "\n",
    "# **Set x-axis to show only 1, 2, 3, 4, 5**\n",
    "ax.set_xticks([1, 2, 3, 4, 5])  # Ensure only these values appear on x-axis\n",
    "\n",
    "ax.grid(True)\n",
    "ax.legend(loc='upper left', fontsize=14)\n",
    "\n",
    "# Set y-axis range\n",
    "ax.set_ylim(0, 1000)  # <---- Set y-axis from 0 to 1000\n",
    "\n",
    "# Adjust layout\n",
    "plt.tight_layout()\n",
    "\n",
    "# Save the figure\n",
    "evi_histogram_path = 'fig_2b.png'\n",
    "plt.savefig(evi_histogram_path)\n",
    "\n",
    "# Display the figure\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "40f3c68e-e908-4ced-840a-50c30555725f",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "1abbdda4-8af0-4991-b3b1-fc574f43b730",
   "metadata": {},
   "source": [
    "# 3. Figure 3(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "85fc0f1c-cf6a-4033-b0e0-17882b1c0ad6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Split the data into two groups\n",
    "group1 = df[df['Position'].isin(['Pro-Impeachment'])]\n",
    "group2 = df[df['Position'].isin(['Anti-Impeachment'])]\n",
    "\n",
    "# Calculate mean and std for each group\n",
    "mean1 = group1['Martial Law Necessary for Security'].mean()\n",
    "std1 = group1['Martial Law Necessary for Security'].std()\n",
    "mean2 = group2['Martial Law Necessary for Security'].mean()\n",
    "std2 = group2['Martial Law Necessary for Security'].std()\n",
    "\n",
    "# **Set bins to align bars with 1, 2, 3, 4, 5**\n",
    "bins = np.array([0.5, 1.5, 2.5, 3.5, 4.5, 5.5])  # Ensures bars are centered on 1, 2, 3, 4, 5\n",
    "\n",
    "# Compute histogram data without plotting\n",
    "n1, _ = np.histogram(group1['Martial Law Necessary for Security'], bins=bins)\n",
    "n2, _ = np.histogram(group2['Martial Law Necessary for Security'], bins=bins)\n",
    "\n",
    "# Define bar width and shift each group slightly\n",
    "bar_width = 0.3  # Ensure bars are not too wide\n",
    "shift = bar_width / 2  # Shift amount\n",
    "\n",
    "# Plot the histograms\n",
    "fig, ax = plt.subplots(figsize=(5, 7))\n",
    "\n",
    "# X positions for bars (centers on 1, 2, 3, 4, 5)\n",
    "bar_positions = np.array([1, 2, 3, 4, 5])\n",
    "\n",
    "# Plot for group 1 (Pro-Impeachment)\n",
    "ax.bar(bar_positions - shift, n1, width=bar_width, color='#b30000', \n",
    "       alpha=1, label='Pro-Impeachment', edgecolor='black', hatch='//')\n",
    "\n",
    "# Add numbers on bars for group 1 (except zero)\n",
    "for count, x_pos in zip(n1, bar_positions):\n",
    "    if count > 0:\n",
    "        ax.text(x_pos - shift, count + 10, str(int(count)), \n",
    "                ha='center', fontsize=12, color='#b30000')\n",
    "\n",
    "ax.axvline(mean1, color='#b30000', linestyle='dashed', linewidth=3)\n",
    "textstr1 = f'Mean: {mean1:.4f}\\nStd Dev: {std1:.4f}'\n",
    "props = dict(boxstyle='round', facecolor='white', alpha=0.5)\n",
    "ax.text(0.03, 0.85, textstr1, transform=ax.transAxes, fontsize=14, \n",
    "        verticalalignment='top', bbox=props, color='#b30000')\n",
    "\n",
    "# Plot for group 2 (Anti-Impeachment)\n",
    "ax.bar(bar_positions + shift, n2, width=bar_width, color='#008ae6', \n",
    "       alpha=1, label='Anti-Impeachment', edgecolor='black', hatch='xx')\n",
    "\n",
    "# Add numbers on bars for group 2 (except zero)\n",
    "for count, x_pos in zip(n2, bar_positions):\n",
    "    if count > 0:\n",
    "        ax.text(x_pos + shift, count + 10, str(int(count)), \n",
    "                ha='center', fontsize=12, color='#008ae6')\n",
    "\n",
    "ax.axvline(mean2, color='#008ae6', linestyle='dashed', linewidth=3)\n",
    "textstr2 = f'Mean: {mean2:.4f}\\nStd Dev: {std2:.4f}'\n",
    "props = dict(boxstyle='round', facecolor='white', alpha=0.5)\n",
    "ax.text(0.03, 0.75, textstr2, transform=ax.transAxes, fontsize=14, \n",
    "        verticalalignment='top', bbox=props, color='#008ae6')\n",
    "\n",
    "# Set labels and tick parameters\n",
    "ax.set_xlabel('Martial Law Necessary for Security', fontsize=14)\n",
    "ax.set_ylabel('', fontsize=18)\n",
    "ax.tick_params(axis='x', labelsize=14)\n",
    "ax.tick_params(axis='y', labelsize=12)\n",
    "\n",
    "# **Set x-axis to show only 1, 2, 3, 4, 5**\n",
    "ax.set_xticks([1, 2, 3, 4, 5])  # Ensure only these values appear on x-axis\n",
    "\n",
    "ax.grid(True)\n",
    "ax.legend(loc='upper left', fontsize=14)\n",
    "\n",
    "# Set y-axis range\n",
    "ax.set_ylim(0, 1000)  # <---- Set y-axis from 0 to 1000\n",
    "\n",
    "# Adjust layout\n",
    "plt.tight_layout()\n",
    "\n",
    "# Save the figure\n",
    "evi_histogram_path = 'fig_3a.png'\n",
    "plt.savefig(evi_histogram_path)\n",
    "\n",
    "# Display the figure\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "35756582-7fcc-4eb0-9b6f-44714fe88915",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "c43355aa-9ca5-4efc-9117-ff39f3afee57",
   "metadata": {},
   "source": [
    "# 3. Figure 3(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "43535d28-5aec-4157-811d-73a44f1953a2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Split the data into two groups\n",
    "group1 = df[df['Position'].isin(['Pro-Impeachment'])]\n",
    "group2 = df[df['Position'].isin(['Anti-Impeachment'])]\n",
    "\n",
    "# Calculate mean and std for each group\n",
    "mean1 = group1['Past Martial Laws Justified'].mean()\n",
    "std1 = group1['Past Martial Laws Justified'].std()\n",
    "mean2 = group2['Past Martial Laws Justified'].mean()\n",
    "std2 = group2['Past Martial Laws Justified'].std()\n",
    "\n",
    "# **Set bins to align bars with 1, 2, 3, 4, 5**\n",
    "bins = np.array([0.5, 1.5, 2.5, 3.5, 4.5, 5.5])  # Ensures bars are centered on 1, 2, 3, 4, 5\n",
    "\n",
    "# Compute histogram data without plotting\n",
    "n1, _ = np.histogram(group1['Past Martial Laws Justified'], bins=bins)\n",
    "n2, _ = np.histogram(group2['Past Martial Laws Justified'], bins=bins)\n",
    "\n",
    "# Define bar width and shift each group slightly\n",
    "bar_width = 0.3  # Ensure bars are not too wide\n",
    "shift = bar_width / 2  # Shift amount\n",
    "\n",
    "# Plot the histograms\n",
    "fig, ax = plt.subplots(figsize=(5, 7))\n",
    "\n",
    "# X positions for bars (centers on 1, 2, 3, 4, 5)\n",
    "bar_positions = np.array([1, 2, 3, 4, 5])\n",
    "\n",
    "# Plot for group 1 (Pro-Impeachment)\n",
    "ax.bar(bar_positions - shift, n1, width=bar_width, color='#b30000', \n",
    "       alpha=1, label='Pro-Impeachment', edgecolor='black', hatch='//')\n",
    "\n",
    "# Add numbers on bars for group 1 (except zero)\n",
    "for count, x_pos in zip(n1, bar_positions):\n",
    "    if count > 0:\n",
    "        ax.text(x_pos - shift, count + 10, str(int(count)), \n",
    "                ha='center', fontsize=12, color='#b30000')\n",
    "\n",
    "ax.axvline(mean1, color='#b30000', linestyle='dashed', linewidth=3)\n",
    "textstr1 = f'Mean: {mean1:.4f}\\nStd Dev: {std1:.4f}'\n",
    "props = dict(boxstyle='round', facecolor='white', alpha=0.5)\n",
    "ax.text(0.03, 0.85, textstr1, transform=ax.transAxes, fontsize=14, \n",
    "        verticalalignment='top', bbox=props, color='#b30000')\n",
    "\n",
    "# Plot for group 2 (Anti-Impeachment)\n",
    "ax.bar(bar_positions + shift, n2, width=bar_width, color='#008ae6', \n",
    "       alpha=1, label='Anti-Impeachment', edgecolor='black', hatch='xx')\n",
    "\n",
    "# Add numbers on bars for group 2 (except zero)\n",
    "for count, x_pos in zip(n2, bar_positions):\n",
    "    if count > 0:\n",
    "        ax.text(x_pos + shift, count + 10, str(int(count)), \n",
    "                ha='center', fontsize=12, color='#008ae6')\n",
    "\n",
    "ax.axvline(mean2, color='#008ae6', linestyle='dashed', linewidth=3)\n",
    "textstr2 = f'Mean: {mean2:.4f}\\nStd Dev: {std2:.4f}'\n",
    "props = dict(boxstyle='round', facecolor='white', alpha=0.5)\n",
    "ax.text(0.03, 0.75, textstr2, transform=ax.transAxes, fontsize=14, \n",
    "        verticalalignment='top', bbox=props, color='#008ae6')\n",
    "\n",
    "# Set labels and tick parameters\n",
    "ax.set_xlabel('Past Martial Laws Justified', fontsize=14)\n",
    "ax.set_ylabel('', fontsize=18)\n",
    "ax.tick_params(axis='x', labelsize=14)\n",
    "ax.tick_params(axis='y', labelsize=12)\n",
    "\n",
    "# **Set x-axis to show only 1, 2, 3, 4, 5**\n",
    "ax.set_xticks([1, 2, 3, 4, 5])  # Ensure only these values appear on x-axis\n",
    "\n",
    "ax.grid(True)\n",
    "ax.legend(loc='upper left', fontsize=14)\n",
    "\n",
    "# Set y-axis range\n",
    "ax.set_ylim(0, 1000)  # <---- Set y-axis from 0 to 1000\n",
    "\n",
    "# Adjust layout\n",
    "plt.tight_layout()\n",
    "\n",
    "# Save the figure\n",
    "evi_histogram_path = 'fig_3b.png'\n",
    "plt.savefig(evi_histogram_path)\n",
    "\n",
    "# Display the figure\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fd468a63-1fa2-43a3-9950-81d0bad6e581",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "e1ed2dec-55f4-45ff-a5b0-76d41fa5655d",
   "metadata": {},
   "source": [
    "# 4. Figure 4(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0b4d3a28-2627-4b0c-8015-6d116c2e5c89",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Split the data into two groups\n",
    "group1 = df[df['Position'].isin(['Pro-Impeachment'])]\n",
    "group2 = df[df['Position'].isin(['Anti-Impeachment'])]\n",
    "\n",
    "# Calculate mean and std for each group\n",
    "mean1 = group1['Democracy Priority in Crisis'].mean()\n",
    "std1 = group1['Democracy Priority in Crisis'].std()\n",
    "mean2 = group2['Democracy Priority in Crisis'].mean()\n",
    "std2 = group2['Democracy Priority in Crisis'].std()\n",
    "\n",
    "# **Set bins to align bars with 1, 2, 3, 4, 5**\n",
    "bins = np.array([0.5, 1.5, 2.5, 3.5, 4.5, 5.5])  # Ensures bars are centered on 1, 2, 3, 4, 5\n",
    "\n",
    "# Compute histogram data without plotting\n",
    "n1, _ = np.histogram(group1['Democracy Priority in Crisis'], bins=bins)\n",
    "n2, _ = np.histogram(group2['Democracy Priority in Crisis'], bins=bins)\n",
    "\n",
    "# Define bar width and shift each group slightly\n",
    "bar_width = 0.3  # Ensure bars are not too wide\n",
    "shift = bar_width / 2  # Shift amount\n",
    "\n",
    "# Plot the histograms\n",
    "fig, ax = plt.subplots(figsize=(5, 7))\n",
    "\n",
    "# X positions for bars (centers on 1, 2, 3, 4, 5)\n",
    "bar_positions = np.array([1, 2, 3, 4, 5])\n",
    "\n",
    "# Plot for group 1 (Pro-Impeachment)\n",
    "ax.bar(bar_positions - shift, n1, width=bar_width, color='#b30000', \n",
    "       alpha=1, label='Pro-Impeachment', edgecolor='black', hatch='//')\n",
    "\n",
    "# Add numbers on bars for group 1 (except zero)\n",
    "for count, x_pos in zip(n1, bar_positions):\n",
    "    if count > 0:\n",
    "        ax.text(x_pos - shift, count + 10, str(int(count)), \n",
    "                ha='center', fontsize=12, color='#b30000')\n",
    "\n",
    "ax.axvline(mean1, color='#b30000', linestyle='dashed', linewidth=3)\n",
    "textstr1 = f'Mean: {mean1:.4f}\\nStd Dev: {std1:.4f}'\n",
    "props = dict(boxstyle='round', facecolor='white', alpha=0.5)\n",
    "ax.text(0.03, 0.85, textstr1, transform=ax.transAxes, fontsize=14, \n",
    "        verticalalignment='top', bbox=props, color='#b30000')\n",
    "\n",
    "# Plot for group 2 (Anti-Impeachment)\n",
    "ax.bar(bar_positions + shift, n2, width=bar_width, color='#008ae6', \n",
    "       alpha=1, label='Anti-Impeachment', edgecolor='black', hatch='xx')\n",
    "\n",
    "# Add numbers on bars for group 2 (except zero)\n",
    "for count, x_pos in zip(n2, bar_positions):\n",
    "    if count > 0:\n",
    "        ax.text(x_pos + shift, count + 10, str(int(count)), \n",
    "                ha='center', fontsize=12, color='#008ae6')\n",
    "\n",
    "ax.axvline(mean2, color='#008ae6', linestyle='dashed', linewidth=3)\n",
    "textstr2 = f'Mean: {mean2:.4f}\\nStd Dev: {std2:.4f}'\n",
    "props = dict(boxstyle='round', facecolor='white', alpha=0.5)\n",
    "ax.text(0.03, 0.75, textstr2, transform=ax.transAxes, fontsize=14, \n",
    "        verticalalignment='top', bbox=props, color='#008ae6')\n",
    "\n",
    "# Set labels and tick parameters\n",
    "ax.set_xlabel('Democracy Priority in Crisis', fontsize=14)\n",
    "ax.set_ylabel('', fontsize=18)\n",
    "ax.tick_params(axis='x', labelsize=14)\n",
    "ax.tick_params(axis='y', labelsize=12)\n",
    "\n",
    "# **Set x-axis to show only 1, 2, 3, 4, 5**\n",
    "ax.set_xticks([1, 2, 3, 4, 5])  # Ensure only these values appear on x-axis\n",
    "\n",
    "ax.grid(True)\n",
    "ax.legend(loc='upper left', fontsize=14)\n",
    "\n",
    "# Set y-axis range\n",
    "ax.set_ylim(0, 1000)  # <---- Set y-axis from 0 to 1000\n",
    "\n",
    "# Adjust layout\n",
    "plt.tight_layout()\n",
    "\n",
    "# Save the figure\n",
    "evi_histogram_path = 'fig_4a.png'\n",
    "plt.savefig(evi_histogram_path)\n",
    "\n",
    "# Display t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1198d015-5641-431e-b684-6748b6493965",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "e6bb7b79-2e16-4f0d-9f4c-b78200e04d00",
   "metadata": {},
   "source": [
    "# 4. Figure 4(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "284c2313-3bfe-4dc2-b86f-21de51f81fca",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Split the data into two groups\n",
    "group1 = df[df['Position'].isin(['Pro-Impeachment'])]\n",
    "group2 = df[df['Position'].isin(['Anti-Impeachment'])]\n",
    "\n",
    "# Calculate mean and std for each group\n",
    "mean1 = group1['Security Justifies Freedom Limits'].mean()\n",
    "std1 = group1['Security Justifies Freedom Limits'].std()\n",
    "mean2 = group2['Security Justifies Freedom Limits'].mean()\n",
    "std2 = group2['Security Justifies Freedom Limits'].std()\n",
    "\n",
    "# **Set bins to align bars with 1, 2, 3, 4, 5**\n",
    "bins = np.array([0.5, 1.5, 2.5, 3.5, 4.5, 5.5])  # Ensures bars are centered on 1, 2, 3, 4, 5\n",
    "\n",
    "# Compute histogram data without plotting\n",
    "n1, _ = np.histogram(group1['Security Justifies Freedom Limits'], bins=bins)\n",
    "n2, _ = np.histogram(group2['Security Justifies Freedom Limits'], bins=bins)\n",
    "\n",
    "# Define bar width and shift each group slightly\n",
    "bar_width = 0.3  # Ensure bars are not too wide\n",
    "shift = bar_width / 2  # Shift amount\n",
    "\n",
    "# Plot the histograms\n",
    "fig, ax = plt.subplots(figsize=(5, 7))\n",
    "\n",
    "# X positions for bars (centers on 1, 2, 3, 4, 5)\n",
    "bar_positions = np.array([1, 2, 3, 4, 5])\n",
    "\n",
    "# Plot for group 1 (Pro-Impeachment)\n",
    "ax.bar(bar_positions - shift, n1, width=bar_width, color='#b30000', \n",
    "       alpha=1, label='Pro-Impeachment', edgecolor='black', hatch='//')\n",
    "\n",
    "# Add numbers on bars for group 1 (except zero)\n",
    "for count, x_pos in zip(n1, bar_positions):\n",
    "    if count > 0:\n",
    "        ax.text(x_pos - shift, count + 10, str(int(count)), \n",
    "                ha='center', fontsize=12, color='#b30000')\n",
    "\n",
    "ax.axvline(mean1, color='#b30000', linestyle='dashed', linewidth=3)\n",
    "textstr1 = f'Mean: {mean1:.4f}\\nStd Dev: {std1:.4f}'\n",
    "props = dict(boxstyle='round', facecolor='white', alpha=0.5)\n",
    "ax.text(0.03, 0.85, textstr1, transform=ax.transAxes, fontsize=14, \n",
    "        verticalalignment='top', bbox=props, color='#b30000')\n",
    "\n",
    "# Plot for group 2 (Anti-Impeachment)\n",
    "ax.bar(bar_positions + shift, n2, width=bar_width, color='#008ae6', \n",
    "       alpha=1, label='Anti-Impeachment', edgecolor='black', hatch='xx')\n",
    "\n",
    "# Add numbers on bars for group 2 (except zero)\n",
    "for count, x_pos in zip(n2, bar_positions):\n",
    "    if count > 0:\n",
    "        ax.text(x_pos + shift, count + 10, str(int(count)), \n",
    "                ha='center', fontsize=12, color='#008ae6')\n",
    "\n",
    "ax.axvline(mean2, color='#008ae6', linestyle='dashed', linewidth=3)\n",
    "textstr2 = f'Mean: {mean2:.4f}\\nStd Dev: {std2:.4f}'\n",
    "props = dict(boxstyle='round', facecolor='white', alpha=0.5)\n",
    "ax.text(0.03, 0.75, textstr2, transform=ax.transAxes, fontsize=14, \n",
    "        verticalalignment='top', bbox=props, color='#008ae6')\n",
    "\n",
    "# Set labels and tick parameters\n",
    "ax.set_xlabel('Security Justifies Freedom Limits', fontsize=14)\n",
    "ax.set_ylabel('', fontsize=18)\n",
    "ax.tick_params(axis='x', labelsize=14)\n",
    "ax.tick_params(axis='y', labelsize=12)\n",
    "\n",
    "# **Set x-axis to show only 1, 2, 3, 4, 5**\n",
    "ax.set_xticks([1, 2, 3, 4, 5])  # Ensure only these values appear on x-axis\n",
    "\n",
    "ax.grid(True)\n",
    "ax.legend(loc='upper left', fontsize=14)\n",
    "\n",
    "# Set y-axis range\n",
    "ax.set_ylim(0, 1000)  # <---- Set y-axis from 0 to 1000\n",
    "\n",
    "# Adjust layout\n",
    "plt.tight_layout()\n",
    "\n",
    "# Save the figure\n",
    "evi_histogram_path = 'fig_4b.png'\n",
    "plt.savefig(evi_histogram_path)\n",
    "\n",
    "# Display t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c15ac4db-896d-4842-b77c-c9feba069cea",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
